﻿using System.Text.RegularExpressions;

namespace TrackSystem.IO.Utils
{
    /// <summary>
    /// 常用计算工具
    /// </summary>
    public static class Tools
    {
        private const string patternIP = @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$";
        //private const string patternReg = "[[a-zA-Z_][a-zA-Z0-9_]*]"; 
        private const string patternReg = @"\[\s*[a-zA-Z_][a-zA-Z0-9_]*\s*\]";

        /// <summary>
        /// 检查IP地址是否合法
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IPFormatCheck(string ip)
        {
            return Regex.IsMatch(ip, patternIP);
        }

        /// <summary>
        /// 查找字符串中[]内部的变量名称
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string[] FindRegsName(string str)
        {
            Regex r = new (patternReg);
            MatchCollection mc = r.Matches(str);

            string[] result = new string[mc.Count];
            for (int i = 0; i < mc.Count; i++)
                result[i] = mc[i].Value[1..^1].Trim();

            return result;
        }

        /// <summary>
        /// CRC校验
        /// </summary>
        /// <param name="pDataBytes"></param>
        /// <param name="nLen"></param>
        /// <returns></returns>
        public static ushort CRC16(byte[] pDataBytes, int nLen)
        {
            ushort crc = 0xFFFF;
            ushort polynom = 0xA001;

            for (int i = 0; i < nLen; i++)
            {
                crc ^= pDataBytes[i];
                for (int j = 0; j < 8; j++)
                {
                    if ((crc & 0x01) == 0x01)
                    {
                        crc >>= 1;
                        crc ^= polynom;
                    }
                    else
                        crc >>= 1;
                }
            }
            return crc;
        }

        /// <summary>
        /// 范围截断
        /// </summary>
        /// <param name="x"></param>
        /// <param name="max"></param>
        /// <param name="min"></param>
        /// <returns></returns>
        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        public static double RangeTrunc(double x, double max, double min)
        {
            return (x > max)? max : (x < min)? min : x;
        }
    }
}
